﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using MyCommerce.ManagementBase.Common.Base.Common;
using MyCommerce.Presentation.Orders.IViews;
using MyCommerce.Presentation.Orders.Presenters;
using Innova.Microfinanzas.BusinessEntities;
using Innova.FoundationFramework.DataTypes;
using Infragistics.Win.UltraWinGrid;
using System.Collections;

namespace MyCommerce.Windows.Orders.Views
{
    public partial class NewOrderToSupplierView : BaseForm, INewOrderToSupplierView
    {
        private NewOrderToSupplierPresenter pPresenter;
        private List<Conveyor> pColConveyors;
        private OrderSupplier vOrderLoad = null;

        public NewOrderToSupplierView()
        {
            InitializeComponent();
            pPresenter = new NewOrderToSupplierPresenter(this);
        }

        #region INewOrderToSupplierView Members

        public IList<long> ColSelectedConveyors
        {
            get
            {
                return listConveyors.GetSelectedEntitiesIdList();
            }
            private set
            {
                listConveyors.SetSelectedEntitiesIdList(value);
            }
        }

        public long IdUser 
        {
            get
            {
                return Context.UserId;
            }
        }

        public object ObjSelectedDetail 
        {
            get
            {
                if (gridOrders.ActiveRow != null
                    && gridOrders.ActiveRow.Selected)
                    return gridOrders.ActiveRow.ListObject;
                return null;
            }
        }

        public List<Supplier> ColSuppliers
        {
            set 
            {
                listSuppliers.DisplayMember = "Name";
                listSuppliers.ValueMember = "IdSupplier";
                listSuppliers.DataSource = value;
            }
        }

        public List<Classifier> ColMoneys
        {
            set 
            {
                listMoney.DisplayMember = "Name";
                listMoney.ValueMember = "IdClassifier";
                listMoney.DataSource = value;
            }
        }

        public List<Conveyor> ColConveyors
        {
            set 
            {
                pColConveyors = value;
                listConveyors.SetNodes<Conveyor>(value, "ComposeName", "IdConveyor");
            }
        }

        public long IdSelectedStore
        {
            get;
            set;
        }

        public long IdSelectedOrder
        {
            get;
            set;
        }

        public long IdSupplier
        {
            get
            {
                if (listSuppliers.SelectedIndex != -1)
                    return Convert.ToInt64(listSuppliers.SelectedValue);
                return 0;
            }
            private set
            {
                listSuppliers.SelectedValue = value;
            }
        }

        public long IdMoney
        {
            get 
            {
                if (listMoney.SelectedIndex != -1)
                    return Convert.ToInt64(listMoney.SelectedValue);
                return 0;
            }
            private set
            {
                listMoney.SelectedValue = value;
            }
        }

        public DataTable DTOrderDetail
        {
            get
            {
                gridOrders.UpdateData();
                return (DataTable)gridOrders.DataSource;
            }
            set
            {
                gridOrders.DataSource = value;
                gridOrders.DataBind();
            }
        }

        public void EnableOrderData(bool action)
        {
            listMoney.Enabled = action;
            listSuppliers.Enabled = action;
        }

        public ProductNewOrderDetail InvokeNewDetail(long idSupplier, long idMoney)
        {
            return NewProductDetail.ShowNewDetail(idSupplier, idMoney);
        }

        public void OnAddRemoveNewDetail(ProductNewOrderDetail objNewDetail, bool isNewDetail)
        {
            DataTable dtGrid = DTOrderDetail;            
            if (isNewDetail)
            {
                DataRow objNewRow = dtGrid.NewRow();
                objNewRow["IdProduct"] = objNewDetail.ObjProduct.IdProduct;
                objNewRow["ProductName"] = objNewDetail.ObjProduct.Model;
                objNewRow["Quantity"] = objNewDetail.Quantity;
                objNewRow["UnitPrice"] = objNewDetail.ObjPrice.PurchasePrice;
                objNewRow["TotalBuy"] = objNewDetail.TotalDetail;
                objNewRow["IdProductPrice"] = objNewDetail.ObjPrice.IdProductPrice;
                objNewRow["OtherPurchacePrice"] = objNewDetail.ObjPrice.OtherPurchasePrice;
                foreach (DataColumn objColumn in dtGrid.Columns)
                {
                    if (objColumn.ColumnName.Contains(":PTCV:"))
                    {
                        objNewRow[objColumn.ColumnName] = objNewDetail.ObjPrice.OtherPurchasePrice;
                    }
                }
                dtGrid.Rows.Add(objNewRow);                
            }
            else
            {
                int indexRow = gridOrders.ActiveRow.Index;
                dtGrid.Rows.RemoveAt(indexRow);
            }
            DTOrderDetail = dtGrid;
            CalculateTotals();
        }

        public void CloseAndSetResult(bool result)
        {
            if (result)
                Context.ShowInformationMessageBox("La información se guardó correctamente.", "Creación de pedidos a proveedores.");
            Result = result;
            Close();
        }

        public void AddRemoveConveyor(long idConveyor)
        {
            bool isAddAction = true;
            DataTable dtGrid = DTOrderDetail;
            IList<long> colIds = listConveyors.GetSelectedEntitiesIdList();
            if (!colIds.Contains(idConveyor))
                isAddAction = false;
            if (isAddAction)
            {
                Conveyor objConveyor = pColConveyors.Find(objFilter => objFilter.IdConveyor == idConveyor);
                DataColumn objColumn = new DataColumn(":CCV:" + idConveyor.ToString(), typeof(int));
                objColumn.Caption = "C | " + objConveyor.Code;
                objColumn.DefaultValue = 0;
                dtGrid.Columns.Add(objColumn);

                if (Context.ObjCommandLoad.CommandKey == "DeliveryOrder")
                {
                    DataColumn objColumnE = new DataColumn(":CECV:" + idConveyor.ToString(), typeof(int));
                    objColumnE.Caption = "CE | " + objConveyor.Code;
                    objColumnE.DefaultValue = 0;
                    dtGrid.Columns.Add(objColumnE);

                    DataColumn objColumnNE = new DataColumn(":CNECV:" + idConveyor.ToString(), typeof(int));
                    objColumnNE.Caption = "CNE | " + objConveyor.Code;
                    objColumnNE.DefaultValue = 0;
                    dtGrid.Columns.Add(objColumnNE);
                }
                DataColumn objColumn1 = new DataColumn(":PTCV:" + idConveyor.ToString(), typeof(decimal));
                objColumn1.Caption = "PT | " + objConveyor.Code;
                objColumn1.DefaultValue = 0;
                dtGrid.Columns.Add(objColumn1);

                DataColumn objColumn2 = new DataColumn(":TCV:" + idConveyor.ToString(), typeof(decimal));
                objColumn2.Caption = "Total | " + objConveyor.Code;
                objColumn2.DefaultValue = 0;
                dtGrid.Columns.Add(objColumn2);
            }
            else
            {
                if (dtGrid.Columns.Contains(":CCV:" + idConveyor.ToString()))
                    dtGrid.Columns.Remove(":CCV:" + idConveyor.ToString());
                if (dtGrid.Columns.Contains(":CECV:" + idConveyor.ToString()))
                    dtGrid.Columns.Remove(":CECV:" + idConveyor.ToString());
                if (dtGrid.Columns.Contains(":CNECV:" + idConveyor.ToString()))
                    dtGrid.Columns.Remove(":CNECV:" + idConveyor.ToString());
                if (dtGrid.Columns.Contains(":PTCV:" + idConveyor.ToString()))
                    dtGrid.Columns.Remove(":PTCV:" + idConveyor.ToString());
                if (dtGrid.Columns.Contains(":TCV:" + idConveyor.ToString()))
                    dtGrid.Columns.Remove(":TCV:" + idConveyor.ToString());
            }
            DTOrderDetail = dtGrid;
            FormatGrid();
            CalculateTotals();
        }

        public void LoadOrderSupplier(OrderSupplier objOrder)
        {
            if (objOrder != null)
            {
                vOrderLoad = objOrder;
                IdSelectedStore = objOrder.IdStore;
                IdSupplier = objOrder.IdSupplier;
                IdMoney = objOrder.IdcMoney;
                List<long> colConveyorsId = new List<long>();
                if (objOrder.SubOrderSupplier != null
                    && objOrder.SubOrderSupplier.Count > 0)
                {
                    foreach (var objSubOrder in objOrder.SubOrderSupplier)
                    {
                        if (!colConveyorsId.Contains(objSubOrder.IdConveyor))
                            colConveyorsId.Add(objSubOrder.IdConveyor);
                    }

                    ColSelectedConveyors = colConveyorsId;

                    // armamos el DataTable con el detalle del pedido
                    DataTable dtToLoad = DTOrderDetail;
                    Dictionary<long, int> dicProductIndex = new Dictionary<long, int>();
                    int indexOfProduct = 0;
                    foreach (var objSubOrder in objOrder.SubOrderSupplier)
                    {
                        if (objSubOrder.OrderProductDetail != null
                            && objSubOrder.OrderProductDetail.Count > 0)
                        {
                            foreach (var objDetail in objSubOrder.OrderProductDetail)
                            {
                                if (!dicProductIndex.ContainsKey(objDetail.IdProduct))
                                {
                                    DataRow objNewRow = dtToLoad.NewRow();
                                    objNewRow["IdProduct"] = objDetail.IdProduct;
                                    objNewRow["ProductName"] = objDetail.Product.Model;
                                    objNewRow["Quantity"] = objDetail.Quantity;
                                    objNewRow["UnitPrice"] = objDetail.UnitPrice;
                                    objNewRow["TotalBuy"] = objDetail.TotalPrice;
                                    objNewRow["IdProductPrice"] = 0;
                                    objNewRow["OtherPurchacePrice"] = objDetail.OtherPrice;

                                    if (dtToLoad.Columns.Contains(":CCV:" + objSubOrder.IdConveyor.ToString()))
                                        objNewRow[":CCV:" + objSubOrder.IdConveyor.ToString()] = objDetail.Quantity;
                                    if (dtToLoad.Columns.Contains(":PTCV:" + objSubOrder.IdConveyor.ToString()))
                                        objNewRow[":PTCV:" + objSubOrder.IdConveyor.ToString()] = objDetail.OtherPrice;
                                    if (dtToLoad.Columns.Contains(":TCV:" + objSubOrder.IdConveyor.ToString()))
                                        objNewRow[":TCV:" + objSubOrder.IdConveyor.ToString()] = objDetail.TotalOtherPrice;

                                    dtToLoad.Rows.Add(objNewRow);
                                    dicProductIndex.Add(objDetail.IdProduct, indexOfProduct);
                                    indexOfProduct++;
                                }
                                else
                                {
                                    DataRow objNewRow = dtToLoad.Rows[dicProductIndex[objDetail.IdProduct]];
                                    objNewRow["Quantity"] = Convert.ToInt32(objNewRow["Quantity"]) + objDetail.Quantity;
                                    objNewRow["TotalBuy"] = Convert.ToInt32(objNewRow["TotalBuy"]) + objDetail.TotalPrice;

                                    if (dtToLoad.Columns.Contains(":CCV:" + objSubOrder.IdConveyor.ToString()))
                                        objNewRow[":CCV:" + objSubOrder.IdConveyor.ToString()] = objDetail.Quantity;
                                    if (dtToLoad.Columns.Contains(":PTCV:" + objSubOrder.IdConveyor.ToString()))
                                        objNewRow[":PTCV:" + objSubOrder.IdConveyor.ToString()] = objDetail.OtherPrice;
                                    if (dtToLoad.Columns.Contains(":TCV:" + objSubOrder.IdConveyor.ToString()))
                                        objNewRow[":TCV:" + objSubOrder.IdConveyor.ToString()] = objDetail.TotalOtherPrice;
                                }

                                if (Context.ObjCommandLoad.CommandKey == "DeliveryOrder")
                                {
                                    if (objDetail.OrderDelivery != null
                                        && objDetail.OrderDelivery.Count > 0)
                                    {
                                        int totalDelivery = 0;
                                        foreach (var deliveryDetail in objDetail.OrderDelivery)
                                        {
                                            totalDelivery += deliveryDetail.Quantity;
                                        }
                                        if (dtToLoad.Columns.Contains(":CECV:" + objSubOrder.IdConveyor.ToString()))
                                        {
                                            DataRow objNewRow = dtToLoad.Rows[dicProductIndex[objDetail.IdProduct]];
                                            objNewRow[":CECV:" + objSubOrder.IdConveyor.ToString()] = totalDelivery;
                                        }
                                    }
                                }
                            }
                        }
                    }
                    DTOrderDetail = dtToLoad;
                    CalculateTotals();
                }
            }
            else
                Context.ShowInformationMessageBox("No se encontro la orden elegida, por favor contáctese con el administrador del sistema.", "Detalle orden a proveedores");
        }

        public event EventHandler OnSave;
        public event EventHandler OnSaveDelivery;
        public event EventHandler OnCancel;
        public event EventHandler OnAddDetail;
        public event EventHandler OnRemoveDetail;
        public event GenericEventHandler<long> OnAddRemoveConveyor;
        public event EventHandler OnLoadView;
        public event EventHandler OnLoadOrder;

        #endregion

        private void SetViewMode(bool action)
        {
            listSuppliers.Enabled = false;
            listConveyors.Enabled = false;
            listMoney.Enabled = false;
            commonButtonsToolStrip2.Enabled = false;
            tsSaveButtonToolStrip.Visible = !action;

            foreach (var objColumnGrid in gridOrders.DisplayLayout.Bands[0].Columns)
            {
                objColumnGrid.CellClickAction = CellClickAction.RowSelect;
                objColumnGrid.CellActivation = Activation.NoEdit;
                objColumnGrid.TabStop = false;
                if (!action
                    && objColumnGrid.Key.Contains("::"))
                {
                    objColumnGrid.CellClickAction = CellClickAction.EditAndSelectText;
                    objColumnGrid.CellActivation = Activation.AllowEdit;
                    objColumnGrid.TabStop = true;
                }
                if (Context.ObjCommandLoad.CommandKey == "DeliveryOrder")
                {
                    if (objColumnGrid.Key.Contains(":CNECV:"))
                    {
                        objColumnGrid.CellDisplayStyle = CellDisplayStyle.FormattedText;
                        objColumnGrid.CellActivation = Activation.AllowEdit;
                        objColumnGrid.CellClickAction = CellClickAction.EditAndSelectText;
                        objColumnGrid.TabStop = true;
                    }
                }
            }
        }

        private void CalculateTotals()
        {
            decimal totalProduct = 0;
            decimal totalOthers = 0;
            foreach (var objRow in gridOrders.Rows)
            {
                totalProduct += Convert.ToDecimal(objRow.Cells["TotalBuy"].Value);
                foreach (var objCell in objRow.Cells)
                {
                    if (objCell.Column.Key.Contains(":TCV:"))
                    {
                        totalOthers += Convert.ToDecimal(objCell.Value);
                    }
                }
            }
            fieldTotalProducts.Value = totalProduct;
            fieldTotalOthers.Value = totalOthers;
            fieldTotalOrder.Value = totalProduct + totalOthers;
        }

        private void FormatGrid()
        {
            foreach (var objColumn in gridOrders.DisplayLayout.Bands[0].Columns)
            {
                if (objColumn.Key.Contains(":TCV:"))
                {
                    if (Context.ObjCommandLoad.CommandKey == "DeliveryOrder")
                        objColumn.Hidden = true;
                    objColumn.CellDisplayStyle = CellDisplayStyle.FormattedText;
                    objColumn.Format = "##,###0.00";
                    objColumn.TabStop = false;
                    objColumn.CellClickAction = CellClickAction.RowSelect;
                }
                else if (objColumn.Key.Contains(":CECV:")
                    || objColumn.Key.Contains(":CNECV:")
                    || objColumn.Key.Contains(":PTCV:"))
                {
                    objColumn.CellDisplayStyle = CellDisplayStyle.FormattedText;
                    objColumn.CellClickAction = CellClickAction.EditAndSelectText;
                }
            }

            foreach (var objRow in gridOrders.Rows)
            {
                foreach (var objCell in objRow.Cells)
                {
                    if (objCell.Column.Key.Contains(":PTCV:"))
                    {
                        objCell.Value = objRow.Cells["OtherPurchacePrice"].Value;
                    }
                }
            }
        }

        private bool ValidateOrderData(bool validateItems)
        {
            bool vResult = true;
            StringBuilder message = new StringBuilder();
            if (listSuppliers.SelectedIndex == -1)
            {
                vResult = false;
                message.AppendLine("Debe seleccionar un proveedor para el pedido.");
            }
            if (listMoney.SelectedIndex == -1)
            {
                vResult = false;
                message.AppendLine("Debe seleccionar una moneda para el pedido.");
            }
            if (validateItems)
            {
                DataTable dtGrid = DTOrderDetail;
                if (dtGrid.Rows.Count <= 0)
                {
                    vResult = false;
                    message.AppendLine("Debe seleccionar al menos un producto para poder realizar el pedido.");
                }
                if (ColSelectedConveyors == null
                    || ColSelectedConveyors.Count == 0)
                {
                    vResult = false;
                    message.AppendLine("Debe seleccionar al menos un pilotero para poder realizar el pedido.");
                }

                if (Context.ObjCommandLoad.CommandKey == "DeliveryOrder")
                {
                    List<long> colIdConveyors = new List<long>();
                    foreach (var objSubOrder in vOrderLoad.SubOrderSupplier)
                    {
                        if (!colIdConveyors.Contains(objSubOrder.IdConveyor))
                        {
                            colIdConveyors.Add(objSubOrder.IdConveyor);
                        }
                    }
                    foreach (UltraGridRow objRow in gridOrders.Rows)
                    {
                        foreach (var idConveyor in colIdConveyors)
                        {
                            int totalDelivery = Convert.ToInt32(objRow.Cells[":CCV:" + idConveyor.ToString()].Value);
                            int deliveryPastQuantity = Convert.ToInt32(objRow.Cells[":CECV:" + idConveyor.ToString()].Value);
                            int deliveryNew = Convert.ToInt32(objRow.Cells[":CNECV:" + idConveyor.ToString()].Value);
                            if ((deliveryNew + deliveryPastQuantity) > totalDelivery)
                            {
                                vResult = false;
                                message.AppendLine("La cantidad de la entrega para el item: " + objRow.Cells["ProductName"].Value.ToString() + ". No puede ser mayor que el total asignado al pilotero.");
                            }
                        }
                    }
                }
                else
                {
                    foreach (var objRow in gridOrders.Rows)
                    {
                        int totalProduct = Convert.ToInt32(objRow.Cells["Quantity"].Value);
                        int totalConveyors = 0;
                        foreach (var objCell in objRow.Cells)
                        {
                            if (objCell.Column.Key.Contains(":CCV:"))
                            {
                                totalConveyors += Convert.ToInt32(objCell.Value);
                            }
                        }
                        if (totalProduct != totalConveyors)
                        {
                            vResult = false;
                            message.AppendLine("La cantidad distribuida entre los piloteros debe ser igual a la cantidad total del producto para el item: " + objRow.Cells["ProductName"].Value.ToString() + ".");
                        }
                    }
                }
            }

            if (!vResult)
                Context.ShowErrorMessageBox(message.ToString(), "Pedidos a proveedores");
            return vResult;
        }

        private void tsSaveButtonToolStrip_Click(object sender, EventArgs e)
        {
            try
            {
                if (Context.ObjCommandLoad.CommandKey == "DeliveryOrder")
                {
                    if (ValidateOrderData(true))
                    {
                        if (OnSaveDelivery != null)
                            OnSaveDelivery(this, new EventArgs());
                    }
                }
                else
                {
                    if (ValidateOrderData(true))
                    {
                        if (OnSave != null)
                        {
                            OnSave(this, new EventArgs());
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                Context.HandleException(ex);
            }
        }

        private void tsCancelButtonToolStrip_Click(object sender, EventArgs e)
        {
            if (OnCancel != null)
                OnCancel(this, new EventArgs());
        }

        private void tsAddItemToolStripButton_Click(object sender, EventArgs e)
        {
            if (ValidateOrderData(false))
            {
                if (OnAddDetail != null)
                    OnAddDetail(this, new EventArgs());
            }
        }

        private void tsRemoveItemToolStripButton_Click(object sender, EventArgs e)
        {
            if (ObjSelectedDetail != null)
            {
                if (Context.ShowQuestionMessageBox("¿Desea eliminar este detalle?", "Eliminar detalle") == System.Windows.Forms.DialogResult.Yes)
                {
                    if (OnRemoveDetail != null)
                    {
                        OnRemoveDetail(this, new EventArgs());
                    }
                }
            }
            else
                Context.ShowInformationMessageBox("Debe seleccionar un detalle para poder eliminarlo.", "Eliminar detalle");
        }

        private void generalTree1_OnNodeChecked(object sender, long id)
        {
            if (OnAddRemoveConveyor != null)
                OnAddRemoveConveyor(this, new GenericEventArgs<long>(id));
        }

        private void NewOrderToSupplierView_Load(object sender, EventArgs e)
        {
            InitializeDataGrid();
            if (OnLoadView != null)
                OnLoadView(this, new EventArgs());
            if (Context.ObjCommandLoad.CommandKey == "NewOrder")
            {
                if (Parameter != null)
                    IdSelectedStore = Convert.ToInt64(Parameter);
            }
            else if (Context.ObjCommandLoad.CommandKey == "ViewOrder"
                || Context.ObjCommandLoad.CommandKey == "DeliveryOrder")
            {
                bool isViewMode = Context.ObjCommandLoad.CommandKey == "ViewOrder";
                if (Parameter != null)
                {
                    IdSelectedOrder = Convert.ToInt64(Parameter);
                    if (OnLoadOrder != null)
                        OnLoadOrder(this, new EventArgs());
                    SetViewMode(isViewMode);
                }
            }           
        }

        private void InitializeDataGrid()
        {
            DataTable dtGrid = new DataTable();
            dtGrid.Columns.Add("IdProduct", typeof(long));
            dtGrid.Columns.Add("ProductName", typeof(string));
            dtGrid.Columns.Add("Quantity", typeof(int));
            dtGrid.Columns.Add("UnitPrice", typeof(decimal));
            dtGrid.Columns.Add("TotalBuy", typeof(decimal));
            dtGrid.Columns.Add("IdProductPrice", typeof(long));
            dtGrid.Columns.Add("OtherPurchacePrice", typeof(long));

            DTOrderDetail = dtGrid;
        }

        private void gridOrders_AfterCellUpdate(object sender, Infragistics.Win.UltraWinGrid.CellEventArgs e)
        {
            if (e.Cell.Column.Key == "UnitPrice")
            {
                e.Cell.Row.Cells["TotalBuy"].Value = Convert.ToDecimal(e.Cell.Value) * Convert.ToDecimal(e.Cell.Row.Cells["Quantity"].Value);
            }
            else if (e.Cell.Column.Key.Contains(":CCV:"))
            {
                string conveyorKey = e.Cell.Column.Key.Split(new string[] { ":CCV:" }, StringSplitOptions.RemoveEmptyEntries)[0];
                e.Cell.Row.Cells[":TCV:" + conveyorKey].Value = Convert.ToDecimal(e.Cell.Value) * Convert.ToDecimal(e.Cell.Row.Cells[":PTCV:" + conveyorKey].Value);
            }
            else if (e.Cell.Column.Key.Contains(":PTCV:"))
            {
                string conveyorKey = e.Cell.Column.Key.Split(new string[] { ":PTCV:" }, StringSplitOptions.RemoveEmptyEntries)[0];
                e.Cell.Row.Cells[":TCV:" + conveyorKey].Value = Convert.ToDecimal(e.Cell.Value) * Convert.ToDecimal(e.Cell.Row.Cells[":CCV:" + conveyorKey].Value);
            }
            gridOrders.DataBind();
            CalculateTotals();
        }        
    }
}